<?php


namespace App\Services;

use App\Models\Dept\Zone;
use App\Models\DeptModel;
use App\Models\PositionModel;
use App\Models\User\Cid;
use App\Models\UserModel;
use App\Models\Warehouse\Dept;
use function PHPUnit\Framework\isEmpty;

/**
 * 部门管理-服务类
 * @author aaron
 * @since 2020/11/11
 * Class DeptService
 * @package App\Services
 */
class DeptService extends BaseService
{
    const ENGINEER_CODE = '售后工程师';
    const CHARGE_CODE = '区域主管';
    const MANAGER_CODE = '区域经理';

    private $allDept = null;
    private $allEngineers = null;

    /**
     * 构造函数
     * @author aaron
     * @since 2020/11/11
     * DeptService constructor.
     */
    public function __construct()
    {
        $this->model = new DeptModel();
        if (is_null($this->allDept)) {
            $depts = DeptModel::all()->toArray();
            $this->allDept = $depts;
        }
    }

    /**
     * 获取数据列表
     * @return array
     * @since 2020/11/11
     * @author aaron
     */
    public function getList()
    {
        $param = request()->all();

        // 查询条件
        $map = [];

        // 部门名称
        $name = getter($param, "name");
        if ($name) {
            $map[] = ['name', 'like', "%{$name}%"];
        }
        $list = $this->model->getList($map, [['sort', 'asc']]);
        return message("操作成功", true, $list);
    }

    /**
     * 获取部门列表
     * @return array
     * @since 2021/5/26
     * @author aaron
     */
    public function getDeptList()
    {
        $deptList = $this->model
            ->where("mark", "=", 1)
            ->get()
            ->toArray();
        return message("操作成功", true, $deptList);
    }

    public function getAllChildIds($id, &$childIds = [])
    {
        $allDepts = collect($this->allDept)->keyBy('id')->toArray();
        foreach ($allDepts as $deptId => $dept) {
            if (!$dept['mark']) {
                continue;
            }
            if ($id == $dept['pid']) {
                $childIds[] = $deptId;
                unset($allDepts[$deptId]);
                self::getAllChildIds($deptId, $childIds);
            }
        }
        return $childIds;
    }

    public function getAllParentIds($parentId, &$parentIds = [])
    {
        $allDepts = collect($this->allDept)->keyBy('id')->toArray();
        foreach ($allDepts as $id => $dept) {
            if ($parentId == $id) {
                $parentIds[] = $dept['id'];
                unset($allDepts[$id]);
                self::getAllParentIds($dept['pid'], $parentIds);
            }
        }
        return $parentIds;
    }

    public function getAllUsers($id)
    {
        $dept = DeptModel::find($id);
        $perPage = (int)request('limit');
        if ($perPage < 1) {
            $perPage = 1;
        }

        $childIds = $this->getAllChildIds($id);
        $ids = array_unique(array_merge($childIds, [intval($id)]));
        $builder = UserModel::query()
            ->whereIn('dept_id', $ids);
        $builder->where('mark', 1);
        $builder->orderByDesc('id');
        $result = $builder->paginate($perPage);
        $result->transform(function ($item) use ($dept) {
            $item->dept_name = $dept->name ?? '';
            return $item;
        });
        return $result;
    }

    public function getEngineers()
    {
        $engineers = $this->getAllEngineers();
        $firstLevels = $this->firstLevelDepts();
        $result = [];
        foreach ($firstLevels as $firstLevel) {
            $secondLevels = $this->subDepts($firstLevel['id']);
            $firstSub = [];
            foreach ($secondLevels as $secondLevel) {
                $thirdLevels = $this->subDepts($secondLevel['id']);
                $secondSubs = [];
                foreach ($thirdLevels as $thirdLevel) {
                    $thirdLevelId = $thirdLevel['id'];
                    $allChildIds = self::getAllChildIds($thirdLevelId);
                    $thirdIds = array_merge($allChildIds, [$thirdLevelId]);
                    $thirdEngineers = [];
                    foreach ($engineers as $engineer) {
                        if (!in_array($engineer['dept_id'], $thirdIds)) {
                            continue;
                        }
                        $thirdEngineers[] = $engineer;
                    }
                    $thirdLevel['sub'] = $thirdEngineers;
                    $secondSubs[] = $thirdLevel;
                }
                $secondLevel['sub'] = $secondSubs;
                $firstSub[] = $secondLevel;
            }
            $firstLevel['sub'] = $firstSub;
            $result[] = $firstLevel;
        }
        return $result;
    }

    private function firstLevelDepts()
    {
        $results = [];
        foreach ($this->allDept as $item) {
            if ($item['pid']) {
                continue;
            }
            $results[] = $item;
        }
        return $results;
    }

    private function subDepts($id)
    {
        $results = [];
        foreach ($this->allDept as $item) {
            if ($item['pid'] != $id) {
                continue;
            }
            $results[] = $item;
        }
        return $results;
    }

    public function getAllEngineers()
    {
        if (!is_null($this->allEngineers)) {
            return $this->allEngineers;
        }
        $builder = UserModel::query()
            ->select(['user.*'])
            ->join('position as p', 'p.id', '=', 'user.position_id')
            ->where('p.name', self::ENGINEER_CODE);
        $engines = $builder->get()->toArray();
        $results = [];
        foreach ($engines as $engine) {
            $engine['name'] = $engine['realname'];
            $results[] = $engine;
        }
        $this->allEngineers = $results;
        return $this->allEngineers;
    }

    /**
     * 获取部门负责人(含所有顶级部门)
     *
     * @param int $id 部门ID
     */
    public function getLeaders(int $id)
    {
        if (!$id) {
            return null;
        }
        $parentIds = $this->getAllParentIds($id);
        $ids = array_unique(array_merge([$id], $parentIds));
        $leaders = UserModel::query()
            ->select(['user.*'])
            ->join('position', 'position.id', '=', 'user.position_id')
            ->where('position.name', '=', '区域负责人')
            ->whereIn('user.dept_id', $ids)
            ->get()
            ->toArray();
        return $leaders;
    }

    /**
     * 根据 省份ID 获取区域（含顶级区域）负责人
     * 岗位tag: 区域主管
     * 省份 -> 所属部门 -> 所有顶级部门 -> 所有部门的 负责人的ID
     * @param int $provinceId
     * @return array
     */
    public function getLeaderIdsByProvinceId($provinceId)
    {
        if (!$provinceId) {
            return [];
        }
        $deptIds = $this->getDeptIdsByProvinceId($provinceId);
        if (empty($deptIds)) {
            return [];
        }
        $leaderBuilder = UserModel::query()
            ->select(['user.id', 'user.realname', 'position.name'])
            ->join('position', 'user.position_id', '=', 'position.id')
            ->where('position.name', self::CHARGE_CODE)
            ->whereIn('user.dept_id', $deptIds)
            ->get()
            ->pluck('id');
        return $leaderBuilder->toArray();
    }

    /**
     * 根据部门ID获取所有区域主管信息
     *
     * @param $deptId
     */
    public function getLeadersById($deptId)
    {
        $parentIds = $this->getAllParentIds($deptId);
        $deptIds = array_unique(array_merge([$deptId], $parentIds));

        $users = UserModel::query()
            ->select(['user.id', 'user.realname'])
            ->join('position as p', 'p.id', '=', 'user.position_id')
            ->where('p.name', '=', self::CHARGE_CODE)
            ->whereIn('user.dept_id', $deptIds)
            ->get();
        return $users;
    }

    /**
     * 根据 省份ID 获取区域（含顶级区域）负责人
     * 岗位tag: 区域经理
     * 省份 -> 所属部门 -> 所有顶级部门 -> 所有部门的 负责人的ID
     * @param int $provinceId
     * @return array
     */
    public function getManagerIdsByProvinceId($provinceId)
    {
        if (!$provinceId) {
            return [];
        }
        $deptIds = $this->getDeptIdsByProvinceId($provinceId);
        if (empty($deptIds)) {
            return [];
        }
        $leaders = $this->getLeadersByDeptIds($deptIds);
        return collect($leaders)->pluck('id')->toArray();
    }

    private function getLeadersByDeptIds($deptIds)
    {
        $leaderBuilder = UserModel::query()
            ->select(['user.id', 'user.realname', 'position.name'])
            ->join('position', 'user.position_id', '=', 'position.id')
            ->where('position.name', self::MANAGER_CODE)
            ->whereIn('user.dept_id', $deptIds)
            ->where('user.mark', '=', 1)
            ->get();
        return $leaderBuilder->toArray();
    }

    /**
     * 根据部门ID获取该部门的所有区域经理
     * @param $deptId
     * @return array
     */
    public function getManagersByDeptId($deptId, $getParents = true)
    {
        if (!$deptId) {
            return [];
        }
        $parentIds = $this->getAllParentIds($deptId);
        if ($getParents) {
            $ids = array_unique(array_merge([$deptId], $parentIds));
        } else {
            $ids = [$deptId];
        }
        $leaders = $this->getLeadersByDeptIds($ids);
        if (!$leaders) {
            return [];
        }
        $results = [];
        foreach ($leaders as $leader) {
            $results[] = [
                'id' => $leader['id'],
                'realname' => $leader['realname']
            ];
        }
        return $results;
    }

    /**
     * 根据 省份ID 获取区域（含顶级区域）负责人 的设备ID
     * 岗位tag: 区域主管
     * 省份 -> 所属部门 -> 所有顶级部门 -> 所有部门的 负责人的ID
     * @param int $provinceId
     */
    public function getLeaderCids(int $provinceId)
    {
        $userIds = $this->getLeaderIdsByProvinceId($provinceId);
        if (empty($userIds)) {
            return [];
        }
        $cids = Cid::query()->whereIn('user_id', $userIds)->get()->pluck('device_id')->toArray();
        return $cids;
    }

    /**
     * 根据部门ID， 获取该部门及所有子部门的所有负责区域
     * @param $id
     */
    public function getAllProvinceIds($id)
    {
        $allChildIds = $this->getAllChildIds($id);
        $deptIds = array_unique(array_merge([$id], $allChildIds));
        $provinceIdData =  Zone::query()
            ->whereIn('dept_id', $deptIds)
            ->get()
            ->pluck('city_id')
            ->toArray();
        return array_unique($provinceIdData);
    }

    /**
     * 是否是品质工程师
     *
     * 属于品质部及其所有子部门
     *
     * @param $userDeptId int 工程师所在部门
     * @return bool
     */
    public function isQuantityEngineer($userDeptId): bool
    {
        $depts = collect($this->allDept)->keyBy('name')->toArray();
        $quantityDept = $depts['品质部'] ?? [];
        if (empty($quantityDept)) {
            return false;
        }
        $quantityDeptId = $quantityDept['id'];
        $subDeptIds = $this->getAllChildIds($quantityDeptId);
        $allQuantityDeptIds = array_merge([$quantityDeptId], $subDeptIds);
        if (in_array($userDeptId, $allQuantityDeptIds)) {
            return true;
        }
        return false;
    }

    /**
     * 当前用户是否是区域经理
     * @param $userId
     * @return bool
     */
    public function isManagerEngineer($userId): bool
    {
        $r = PositionModel::query()
            ->from('position as p')
            ->join('user as u','u.position_id', '=', 'p.id')
            ->where('p.name', '=', self::MANAGER_CODE)
            ->where('u.id', '=', $userId)
            ->count();
        return (bool)$r;
    }

    /**
     * 根据省份ID，获取所属部门及顶级部门ID
     *
     * @param int $provinceId
     * @return array
     */
    private function getDeptIdsByProvinceId(int $provinceId)
    {
        $currentDept = DeptModel::query()
            ->select(['dept.*'])
            ->join('dept_zone', 'dept_zone.dept_id', 'dept.id')
            ->where('dept_zone.city_id', $provinceId)
            ->first();
        if (empty($currentDept)) {
            return [];
        }

        $parentDeptIds = $this->getAllParentIds($currentDept->pid);
        $allDeptIds = array_unique(array_merge([$currentDept->id], $parentDeptIds));
        return $allDeptIds;
    }
}
